﻿using System.Collections.Generic;
using UnityEngine;

namespace Neatly.Tween
{
    public static class TweenHelper
    {
        public static float GetTweenTypeRatio(TweenType tweenType, float x)
        {
            if (tweenType == TweenType.EaseOutQuint)
            {
                return x >= 1 ? 1 : 1 - Mathf.Pow(2, -10 * x);
            }
            if (tweenType == TweenType.EaseOutCubic)
            {
                var t = x - 1;
                return t * t * t + 1;
            }
            if (tweenType == TweenType.EaseInSine)
            {
                return 1 - Mathf.Cos((x * Mathf.PI) / 2);
            }
            if (tweenType == TweenType.EaseOutSine)
            {
                return Mathf.Sin((x * Mathf.PI) / 2);
            }
            if (tweenType == TweenType.EaseInOutSine)
            {
                return -(Mathf.Cos(Mathf.PI * x) - 1) / 2;
            }
            if (tweenType == TweenType.EaseInQuad)
            {
                return x * x;
            }
            if (tweenType == TweenType.EaseOutQuad)
            {
                return 1 - (1 - x) * (1 - x);
            }
            if (tweenType == TweenType.EaseInOutQuad)
            {
                return x < 0.5 ? 2 * x * x : 1 - Mathf.Pow(-2 * x + 2, 2) / 2;
            }
            return x;
        }
        private static readonly List<List<Vector3>> _CacheVectorListPool = new List<List<Vector3>>();
        private static List<Vector3> GetCacheVectorList()
        {
            if (_CacheVectorListPool.Count <= 0)
            {
                return new List<Vector3>();
            }
            int index = _CacheVectorListPool.Count - 1;
            var list = _CacheVectorListPool[index];
            _CacheVectorListPool.RemoveAt(index);
            return list;
        }
        private static void ReleaseCacheVectorList(List<Vector3> list)
        {
            list.Clear();
            _CacheVectorListPool.Add(list);
        }
        public static Vector3 Bezier(float t, List<Vector3> pointList, bool isRelease)
        {
            if (pointList.Count == 2)
            {
                return Vector3.Lerp(pointList[0], pointList[1], t);
            }
            var pool = GetCacheVectorList();
            for (var i = 0; i < pointList.Count - 1; i++)
            {
                pool.Add(Vector3.Lerp(pointList[i], pointList[i + 1], t));
            }
            if (isRelease)
            {
                ReleaseCacheVectorList(pointList);
            }
            return Bezier(t, pool, true);
        }
    }
}